package org.dromara.system.controller;

import java.util.List;
import java.util.Objects;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.common.core.utils.BeanUtils;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.PayApp;
import org.dromara.system.domain.bo.PayAppAddBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.kernel.RedisAlgorithmKernel;
import org.dromara.system.mapper.PayAppMapper;
import org.dromara.system.service.ISysUserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.system.domain.bo.PayAppBo;
import org.dromara.system.service.IPayAppService;
import org.dromara.common.mybatis.core.page.TableDataInfo;

/**
 * 应用列表
 * 前端访问路由地址为:/system/PayApp
 *
 * @author Gavino
 * @date 2024-10-22
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/PayApp")
public class PayAppController extends BaseController {

    private final IPayAppService payAppService;
    private final ISysUserService userService;
    private final RedisAlgorithmKernel redisAlgorithmKernel;
    private final PayAppMapper baseMapper;

    /**
     * 查询应用列表列表
     */
    @SaCheckPermission("system:PayApp:list")
    @GetMapping("/list")
    public TableDataInfo<?> list(PayAppBo bo, PageQuery pageQuery) {

        Class<?> clazz = PayAppVo.class;
        if (LoginHelper.isClient()) {
          clazz = PayAppClientVo.class;
        }
        return payAppService.queryPageList(bo, pageQuery, clazz);
    }

    /**
     * 查询应用列表列表
     */
    @GetMapping("/queryList")
    public R<?> queryList(PayAppBo bo) {
        return R.ok(payAppService.queryList(bo, PayAppSelectVo.class));
    }

    /**
     * 导出应用列表列表
     */
    @SaCheckPermission("system:PayApp:export")
    @Log(title = "应用列表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(PayAppBo bo, HttpServletResponse response) {

        if (LoginHelper.isClient()) {
            // 返回 PayAppClientVo 对象
            List<PayAppClientVo> list = payAppService.queryList(bo, PayAppClientVo.class);
            ExcelUtil.exportExcel(list, "应用列表", PayAppClientVo.class, response);
        } else {
            List<PayAppVo> list = payAppService.queryList(bo, PayAppVo.class);
            ExcelUtil.exportExcel(list, "应用列表", PayAppVo.class, response);
        }
    }

    /**
     * 获取应用列表详细信息
     *
     * @param appId 主键
     */
    @SaCheckPermission("system:PayApp:query")
    @GetMapping("/{appId}")
    public R<PayAppVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long appId) {
        return R.ok(payAppService.queryById(appId));
    }

    /**
     * 新增应用列表
     */
    @SaCheckPermission("system:PayApp:add")
    @Log(title = "应用列表", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody PayAppAddBo bo) {
        return payAppService.insertByBo(BeanUtils.copy(bo, PayAppBo.class));
    }

    /**
     * 修改应用列表
     */
    @SaCheckPermission("system:PayApp:edit")
    @Log(title = "应用列表", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody PayAppAddBo bo) {
        return toAjax(payAppService.updateByBo(BeanUtils.copy(bo, PayAppBo.class), true));
    }

    /**
     * 修改应用备注
     */
    @RepeatSubmit()
    @PostMapping("/remark")
    public R<Void> remark(@RequestBody PayAppBo bo) {
        if(bo.getAppId() == null) {
            return R.fail("应用ID不能为空");
        }

        if(bo.getRemark() == null) {
            return R.fail("备注不能为空");
        }

        PayAppBo param = new PayAppBo();
        param.setAppId(bo.getAppId());
        param.setRemark(bo.getRemark());

        return toAjax(payAppService.updateByBo(param, false));
    }

    /**
     * 修改吃单比例
     */
    @SaCheckPermission("system:PayApp:edit")
    @Log(title = "修改吃单比例", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/updateRatio")
    public R<Void> updateRatio(@RequestBody JSONObject json) {
        SysUserVo user = userService.selectUserById(LoginHelper.getLoginUser().getUserId());
        if (!Objects.equals(user.getIsFeign(), 1)) {
            return R.fail("暂无权限");
        }

        if(json.isEmpty()) {
            return R.fail();
        }
        if(!json.containsKey("ratio")) {
            return R.fail("吃单比例参数不能为空");
        }
        if(!json.containsKey("appId")) {
            return R.fail("应用ID不能为空");
        }

        LambdaUpdateWrapper<PayApp> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(PayApp::getAppId, json.getLong("appId"));

        wrapper.set(PayApp::getRatio, json.getBigDecimal("ratio"));
        wrapper.set(PayApp::getRatioMin, json.getBigDecimal("ratioMin"));
        wrapper.set(PayApp::getRatioMax, json.getBigDecimal("ratioMax"));

        if(json.getBoolean("updateTime")) {
            wrapper.set(PayApp::getRatioTime, DateUtils.getNowDate());
        }

        boolean a = baseMapper.update(wrapper) > 0;

        if(a) {
            //删除缓存吃单数量
            redisAlgorithmKernel.delFeignCount(json.getLong("appId"));
        }

        return toAjax(a);
    }

    /**
     * 删除应用列表
     *
     * @param appIds 主键串
     */
    @SaCheckPermission("system:PayApp:remove")
    @Log(title = "应用列表", businessType = BusinessType.DELETE)
    @DeleteMapping("/{appIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] appIds) {
        return toAjax(payAppService.deleteWithValidByIds(List.of(appIds), true));
    }
}
